{==============================================================================}
{  Acroprise Multi-Language Components                                         }
{                                                                              }
{  Copyright (C), 1999-2019, Acroprise Inc.                                    }
{  http://www.acroprise.com.tw                                                 }
{  ALL RIGHTS RESERVED                                                         }
{                                                                              }
{  Author   : Mustapha.Wang                                                    }
{  Version  : 5.2.16.2160                                                      }
{  Creation : 2002/05/06                                                       }
{  Revision :                                                                  }
{  Task     :                                                                  }
{==============================================================================}
unit acroLanguage;
{$I acroMultiLang.Inc}
interface
uses
  Classes,SysUtils
  {$IFDEF Delphi16High}
  ,System.Generics.Defaults
  ,System.Generics.Collections
  {$ELSE}
  {$IFDEF Delphi11High}
  ,Generics.Defaults
  ,Generics.Collections
  {$ENDIF}
  {$ENDIF}
  {$IFDEF MSWindows}
  ,Registry,Windows
  {$ENDIF}
  {$IFDEF UNICODE}
  ,acroCulture_Unicode
  {$ELSE}
  ,acroCulture_Ansi
  {$ENDIF}
  ;
type

  PacroLanguageInfo=^TacroLanguageInfo;
  TacroLanguageInfo=record
    CodePage:integer;
    LongName:PResStringRec;
    LongNameEnglish:string;
    ShortName:string;
    LCID:integer;
    ShortName_Google:string;
  end;

  TacroCodePageList = class(TStringList)
  public
    constructor Create;
    destructor Destroy; override;
  end;

  {$IFDEF Delphi8High}
  TacroLanguageList=class(TList<PacroLanguageInfo>)
  {$ELSE}
  TacroLanguageList=class(TStringList)
  {$ENDIF}
  public
    function GetLCID(ACodePage:integer):integer;
    function GetLCID2(ACodePage:string):string;
    function  GetLanguageInfo(ACodePage:integer):PacroLanguageInfo;
  end;

  TacroLanguage=(
    lngThailand,
    lngJapanese,
    lngChineseSimple,
    lngKorean,
    lngChineseTraditional,
    lngRussian,
    lngEnglish,
    lngGreek,
    lngTurkish,
    lngHebrew,
    lngArabic,
    lngBaltic,
    lngVietnam,
    lngFrench,
    lngSpanish,
    lngPolish,
    lngPortuguese,
    lngItalian,
    lngHungarian,
    lngGermanize,
    lngFinnish,
    lngCzech,
    lngBulgaria,
    lngSwedish,
    lngAlbanian,
    lngDutch,
    lngSylvia,
    lngSlovenian,
    lngLatin,
    lngSlovakian,
    lngIndonesian,
    lngIran);

const
  CODEPAGE_ENG    ='1252';
  CODEPAGE_CHS    ='936';
  CODEPAGE_CHT    ='950';

ResourceString
  S_Thailand=           'Thailand';
  S_Japanese=           'Japanese';
  S_ChineseSimple=      'Chinese Simple';
  S_Korean=             'Korean';
  S_ChineseTraditional= 'Chinese Traditional';
  S_Russian=            'Russian';
  S_English=            'English';
  S_Greek=              'Greek';
  S_Turkish=            'Turkish';
  S_Hebrew=             'Hebrew';
  S_Arabic=             'Arabic';
  S_Baltic=             'Baltic';
  S_Vietnam=            'Vietnam';
  S_French=             'French';
  S_Spanish=            'Spanish';
  S_Polish=             'Polish';
  S_Portuguese=         'Portuguese';
  S_Italian=            'Italian';
  S_Hungarian=          'Hungarian';
  S_Germanize=          'Germanize';
  S_Finnish=            'Finnish';
  S_Czech=              'Czech';
  S_Bulgaria=           'Bulgaria';
  S_Swedish=            'Swedish';
  S_Albanian=           'Albanian';
  S_Dutch=              'Dutch';
  S_Sylvia=             'Sylvia';
  S_Slovenian=          'Slovenian';
  S_Latin=              'Latin';
  S_Slovakian=          'Slovakian';
  S_Indonesian=         'Indonesian';
  S_Iran=               'Iran';

var
  CNST_arrayLanguageInfos:array[TacroLanguage] of TacroLanguageInfo=(
    (CodePage:874;   LongName:@S_Thailand;           LongNameEnglish:S_Thailand;           ShortName:'tal';LCID:1054; ShortName_Google:'th'),
    (CodePage:932;   LongName:@S_Japanese;           LongNameEnglish:S_Japanese;           ShortName:'jpn';LCID:1041; ShortName_Google:'ja'),
	  (CodePage:936;   LongName:@S_ChineseSimple;      LongNameEnglish:S_ChineseSimple;      ShortName:'chs';LCID:2052; ShortName_Google:'zh-CN'),
	  (CodePage:949;   LongName:@S_Korean;             LongNameEnglish:S_Korean;             ShortName:'kor';LCID:1042; ShortName_Google:'ko'),
	  (CodePage:950;   LongName:@S_ChineseTraditional; LongNameEnglish:S_ChineseTraditional; ShortName:'cht';LCID:1028; ShortName_Google:'zh-TW'),
	  (CodePage:1251;  LongName:@S_Russian;            LongNameEnglish:S_Russian;            ShortName:'rus';LCID:1049; ShortName_Google:'ru'),
	  (CodePage:1252;  LongName:@S_English;            LongNameEnglish:S_English;            ShortName:'eng';LCID:1033; ShortName_Google:'en'),
	  (CodePage:1253;  LongName:@S_Greek;              LongNameEnglish:S_Greek;              ShortName:'grk';LCID:1032; ShortName_Google:'gr'),
	  (CodePage:1254;  LongName:@S_Turkish;            LongNameEnglish:S_Turkish;            ShortName:'tur';LCID:1055; ShortName_Google:'tu'),
	  (CodePage:1255;  LongName:@S_Hebrew;             LongNameEnglish:S_Hebrew;             ShortName:'heb';LCID:1037; ShortName_Google:'he'),
    (CodePage:1256;  LongName:@S_Arabic;             LongNameEnglish:S_Arabic;             ShortName:'arb';LCID:1025; ShortName_Google:'ar'),
	  (CodePage:1257;  LongName:@S_Baltic;             LongNameEnglish:S_Baltic;             ShortName:'blt';LCID:1061; ShortName_Google:'ba'),
	  (CodePage:1258;  LongName:@S_Vietnam;            LongNameEnglish:S_Vietnam;            ShortName:'vtn';LCID:1066; ShortName_Google:'vi'),
	  (CodePage:125001;LongName:@S_French;             LongNameEnglish:S_French;             ShortName:'frn';LCID:1036; ShortName_Google:'fr'),
	  (CodePage:125002;LongName:@S_Spanish;            LongNameEnglish:S_Spanish;            ShortName:'esp';LCID:1034; ShortName_Google:'es'),
	  (CodePage:125003;LongName:@S_Polish;             LongNameEnglish:S_Polish;             ShortName:'pol';LCID:1045; ShortName_Google:'po'),
	  (CodePage:125004;LongName:@S_Portuguese;         LongNameEnglish:S_Portuguese;         ShortName:'prt';LCID:1046; ShortName_Google:'pt'),
	  (CodePage:125005;LongName:@S_Italian;            LongNameEnglish:S_Italian;            ShortName:'itl';LCID:1040; ShortName_Google:'it'),
	  (CodePage:125006;LongName:@S_Hungarian;          LongNameEnglish:S_Hungarian;          ShortName:'hug';LCID:1038; ShortName_Google:'hu'),
	  (CodePage:125007;LongName:@S_Germanize;          LongNameEnglish:S_Germanize;          ShortName:'ger';LCID:1031; ShortName_Google:'de'),
	  (CodePage:125008;LongName:@S_Finnish;            LongNameEnglish:S_Finnish;            ShortName:'fnn';LCID:1035; ShortName_Google:'fi'),
    (CodePage:125009;LongName:@S_Czech;              LongNameEnglish:S_Czech;              ShortName:'cez';LCID:1029; ShortName_Google:'cz'),
	  (CodePage:125010;LongName:@S_Bulgaria;           LongNameEnglish:S_Bulgaria;           ShortName:'blg';LCID:1026; ShortName_Google:'bu'),
	  (CodePage:125011;LongName:@S_Swedish;            LongNameEnglish:S_Swedish;            ShortName:'swd';LCID:1053; ShortName_Google:'sw'),
	  (CodePage:125012;LongName:@S_Albanian;           LongNameEnglish:S_Albanian;           ShortName:'alb';LCID:1052; ShortName_Google:'al'),
	  (CodePage:125013;LongName:@S_Dutch;              LongNameEnglish:S_Dutch;              ShortName:'dut';LCID:1043; ShortName_Google:'du'),
	  (CodePage:125014;LongName:@S_Sylvia;             LongNameEnglish:S_Sylvia;             ShortName:'slv';LCID:2074; ShortName_Google:'sy'),
	  (CodePage:125015;LongName:@S_Slovenian;          LongNameEnglish:S_Slovenian;          ShortName:'sle';LCID:1060; ShortName_Google:'sle'),
	  (CodePage:125016;LongName:@S_Latin;              LongNameEnglish:S_Latin;              ShortName:'ltn';LCID:1068; ShortName_Google:'la'),
	  (CodePage:125017;LongName:@S_Slovakian;          LongNameEnglish:S_Slovakian;          ShortName:'sla';LCID:1051; ShortName_Google:'sla'),
	  (CodePage:125201;LongName:@S_Indonesian;         LongNameEnglish:S_Indonesian;         ShortName:'ind';LCID:1057; ShortName_Google:'in'),
	  (CodePage:125601;LongName:@S_Iran;               LongNameEnglish:S_Iran;               ShortName:'irn';LCID:1065; ShortName_Google:'ir'));

var
  gLanguageList:TacroLanguageList;

implementation

const
  REG_CODEPAGE = '\SOFTWARE\Classes\MIME\Database\Codepage';

{ TMyCompare }
{$IFDEF Delphi8High}
type
  TMyCompare=class(TInterfacedObject,IComparer<PacroLanguageInfo>)
  public
    function Compare(const Left, Right: PacroLanguageInfo): Integer;
  end;

function TMyCompare.Compare(const Left, Right: PacroLanguageInfo): Integer;
begin
  if Left^.CodePage<Right^.CodePage then Result:=-1
  else if Left^.CodePage=Right^.CodePage then Result:=0
  else Result:=1;
end;
{$ENDIF}

constructor TacroCodePageList.Create;
  procedure AddCodePage(AIndex:integer;ACodePage,ADescription:string);
  var
    vNode:PCodePageInfo;
  begin
    New(vNode);
    vNode^.Description:=ADescription;
    if AIndex<0 then Self.AddObject(ACodePage,Pointer(vNode))
    else Self.Objects[AIndex]:=Pointer(vNode);
  end;
var
  i: Integer;
begin
  inherited;
  {$IFDEF MSWindows}
  with TRegistry.Create do
  try
    RootKey := HKEY_LOCAL_MACHINE;
    if OpenKey(REG_CODEPAGE, False) then
    begin
      GetKeyNames(Self);
      CloseKey;
      for i:=0 to Self.Count-1 do
      begin
        if OpenKey(REG_CODEPAGE + '\' + Self[i], False) then
        begin
          AddCodePage(i,Self.Strings[i],ReadString('Description'));
          CloseKey;
        end;
      end;
    end;
  finally
    Free;
  end;
  {$ENDIF}
  if Count=0 then
  begin
    AddCodePage(-1,'1252',S_English);
    AddCodePage(-1,'936',S_ChineseSimple);
    AddCodePage(-1,'950',S_ChineseTraditional);
  end;
end;

destructor TacroCodePageList.Destroy;
var
  i: Integer;
begin
  for i:=0 to Self.Count-1 do Dispose(PCodePageInfo(Self.Objects[i]));
  inherited;
end;

function TacroLanguageList.GetLCID(ACodePage: integer): integer;
var
  Index:integer;
  {$IFDEF Delphi8High}
  Item:TCodePageInfo;
  {$ENDIF}
begin
  Result:=-1;
  {$IFDEF Delphi8High}
  Item.CodePage:=ACodePage;
  if Self.BinarySearch(@Item,Index) then
  begin
    Result:=Self[Index]^.CodePage;
  end;
  {$ELSE}
  if Self.Find(InttoStr(ACodePage),index) then
  begin
    Result:=PacroLanguageInfo(Objects[Index])^.LCID;
  end;
  {$ENDIF}
end;

function TacroLanguageList.GetLCID2(ACodePage: string): string;
begin
  Result:=InttoStr(GetLCID(StrToInt(ACodePage)));
end;

function TacroLanguageList.GetLanguageInfo(ACodePage:integer):PacroLanguageInfo;
var
  Index:integer;
  {$IFDEF Delphi8High}
  Item:TCodePageInfo;
  {$ENDIF}
begin
  Result:=nil;
  {$IFDEF Delphi8High}
  Item.CodePage:=ACodePage;
  if Self.BinarySearch(@Item,Index) then
  begin
    Result:=Self[Index];
  end;
  {$ELSE}
  if Find(InttoStr(ACodePage),Index) then
    Result:=PacroLanguageInfo(Objects[Index]);
  {$ENDIF}
end;

var
  vLanguage:TacroLanguage;

initialization
  {$IFDEF Delphi8High}
  gLanguageList:=TacroLanguageList.Create(TMyCompare.Create());
  {$ELSE}
  gLanguageList:=TacroLanguageList.Create;
  {$ENDIF}
  for vLanguage:=Low(TacroLanguage) to High(TacroLanguage) do
  begin
    {$IFDEF Delphi8High}
    gLanguageList.Add(@CNST_arrayLanguageInfos[vLanguage]);
    {$ELSE}
    gLanguageList.AddObject(InttoStr(CNST_arrayLanguageInfos[vLanguage].CodePage),
      @CNST_arrayLanguageInfos[vLanguage]);
    {$ENDIF}
  end;
  gLanguageList.Sort;
finalization
  FreeAndNil(gLanguageList);
end.
